home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™94
/
Talks & Papers
/
Timothy Knox
/
yerk 3.66
/
System source
/
Window
< prev
Wrap
Text File
|
1994-06-24
|
9KB
|
293 lines
\ 5/07/84 NDI Version 1
\ 9/05/84 CBD Version 1.3
\ 9/07/84 CBD Fixed GetVRect:
\ 11/22/84 cbd ctlHit, fixed drag:, grow:
\ 12/08/85 cdn Modified enable: & disable: to flip-flop Null-Evt vectors
\ 12/15/85 cdn Moved FinalSave to Util module
\ 4/15/86 cdn Added Hide: method
\ 5/27/86 cdn Added idle vector; enable:/disable now set actW (active window)
\ 8/07/86 cdn Added deact vector & setact:
\ 8/12/86 cdn Removed extraneous drops in new:
\ 12/26/87 rfl could modify draw: to not set, but to set super to save fprect
\ 11/06/90 rfl example: now uses grayRgn for drag; simplified classinit
\ 11/23/90 rfl added grayRgn word
\ 3/22/91 rfl because of complaints, growbox now erased on grow
\ 4/09/91 rfl also, grow now computes to send next line to bottom if necessary
\ 4/29/91 rfl simplified eraseGrow:...but did not recompile source
\ 10/21/91 rfl added a lot of Michael Hore's window routines, grow box support, etc.
\ moved screenbits from objinit
\ 12/18/91 rfl resID now stored with object, getnew: requires nothing on stack
\ 12/27/91 rfl drag no longer selects window...command key option works as in IM
\ 6/22/92 rfl erasegrow: only works if grow flag is set
\ 9/28/92 rfl added portBit:
\ 10/18/92 rfl added 'part' as parameter for zoom handler...Used to have to use
\ mp2 to get zoom state from methods stack
\ 5/10/93 rfl shortened getnew: and check for resource with error message
\ 5/29/93 rfl removed theWindow; changed thePort to myPort.
\ 1/03/94 rfl added cut, copy and paste methods
Decimal
-1 Constant inFront
0 Variable myPort
129 Constant Thumb
0 Constant docWind
16 Constant rndWind
1 Constant dlgWind
: initFont 9 tsize 4 tfont 0 tMode 0 tFace ;
: grayRgn ( -- l t r b ) $ 9ee -base @ >ptr 2+ get: rect ;
\ ( b -- bool ) make a Forth boolean into a Toolbox boolean
: Bool 8 << makeInt ;
\ save and restore the GrafPort
: savePort myPort +base call GetPort ;
: restPort myPort @ call SetPort ;
\ ( -- l t r b ) leave dimension coordinates of host machine's display
: ScreenBits
$ 904 -base @ -base @ -base 116 -
dup @ unpack
rot 4+ @ unpack
;
\ define the basic Window class, which has no controls
:CLASS Window <Super GrafPort
$ 20 Bytes wind1 \ unmapped
Handle Ctllist \ 1st ctl
$ 0C Bytes wind2 \ unmapped
Rect contRect \ true content
Rect growRect \ grow size rectangle
Rect dragRect \ Drag limits rect
Int growFlg \ true if growable
Int dragFlg \ true if draggable
Int Alive \ true if space exists
Var Idle \ cfa- idle handler
Var Deact \ cfa- deactivate event handler
Var Content \ cfa- content handler
Var Draw \ cfa- draw handler
Var Enact \ cfa- activate event handler
Var Close \ cfa- close handler
Int Resid \ Resource ID
int scrollFlg \ flag to not update fprect for scrolling
Var Zoom \ cfa- zoom word
\ set drag and grow limits based on multiple screen regions
:M SETLIMITS: grayRgn put: dragRect
40 40 getBot: dragRect put: growRect
4 4 inset: dragRect true put: dragFlg true put: growFlg ;M
:M SETZOOM: put: Zoom ;M
:M SETSCROLL: put: scrollFlg ;M
:M SETFPRECT: get: scrollFlg IF get: contRect put: fPrect THEN ;M
\ ( -- ) update the Forth output, scrolling rects
:M SETVIEW: get: portRect get: growFlg
IF swap 15 - swap 15 - THEN put: contRect
setfPrect: self ;M
\ ( n --)
:M PUTRESID: put: resID ;M
\ ( -- )
:M CLOSE: get: alive
IF (abs) call CloseWindow clear: alive exec: close
THEN ;M
\ ( -- ) Make this wind the current GrafPort
:M SET: set: super setfPrect: self ;M
:M PORTBIT: ( -- abs) (abs) 2+ ;M
\ update window with its entire port rectangle as the update region.
:M UPDATE: pushPort set: self
getRect: self put: tempRect update: tempRect
popPort ;M
:M InitNewWindow: setView: [ ^base ]
set: self initFont true put: alive cls ;M
:M PenIntoWind: @xy bottom min gotoxy ;M
\ Define a new window on heap with specified features
:M NEW: { bndsRect tAddr tLen procID vis goAway -- }
Get: Alive 0=
IF 0 (abs) bndsrect +base taddr tlen str255 vis bool
procID makeInt inFront goAway bool 0
call NewWindow drop initNewWindow: self
THEN ;M
\ ( -- ) new window from resource file
:M GETNEW: get: alive 0=
IF 0 int: resid (abs) infront
call GetNewWindow 0= classerr" 170
initNewWindow: self select: [ ^base ]
ELSE drop
THEN ;M
\ ( -- l t r b ) Return the vert. scroll bar rect
:M GETVRECT: GetBotx: portRect 15 -
GetTopy: portRect 1- getBotX: portRect 1+
getBotY: portRect 14 - ;M
\ ( -- l t r b ) Return the horizontal scroll bar rect
:M GETHRECT: getTopX: portRect 1- getBotY: portRect 15 -
getBotX: portRect 14 - getBotY: portRect 1+ ;M
\ ( -- ) update content area
:M DRAW: get: fPrect
(abs) call BeginUpdate
savePort @xy set: self
get: growFlg
IF @xy (abs) call DrawGrowIcon
gotoxy
THEN
exec: draw restport gotoxy \ call user draw routine
(abs) call EndUpdate
put: fPrect ;M
\ ( -- ) Make this the front window
:M SELECT: (abs) call SelectWindow setfPrect: self ;M
\ The idle: method is normally called, (after executing the system tasks),
\ for the front-most window, whenever a null event occurs. It should be a
\ window-specific task. NULL-EVT is the normal word which sends idle:
:M IDLE: exec: idle ;M
\ ( cfa -- ) Install a null event handler for this window
:M SETIDLE: put: idle ;M
\ ( -- ) response to activate event
:M ENABLE: ^base -> actW \ commence idle handler
set: self
get: growFlg IF @xy (abs) call DrawGrowIcon gotoxy THEN
exec: Enact ;M
\ ( -- ) response to deactivate event
:M DISABLE: 0 -> actW
get: growFlg
IF @xy (abs) call DrawGrowIcon gotoxy THEN
exec: deact ;M \ cease idle handler
\ ( enact deact -- ) Set the activate/deactivate event handlers
:M SETACT: put: Deact put: Enact ;M
\ ( -- b ) is this window active ?
:M ACTIVE: 0 call FrontWindow (abs) = ;M
\ ( -- b ) is this window alive?
:M ALIVE: get: alive ;M
\ ( -- ) response to drag region click
:M DRAG: get: dragFlg
IF (abs) Where: fEvent abs: dragRect
call DragWindow
THEN ;M
:M ERASEGROW: get: growFlg
IF getVRect: self 16 + put: tempRect
clear: tempRect update: tempRect
getHRect: self put: temprect clear: temprect update: tempRect
THEN ;M
:M FIXGROW: eraseGrow: self setView: [ ^base ] penIntoWind: self ;M
\ ( w h -- ) reSize window and accumulate update regions
:M SIZE: pack (abs) swap True makeInt
eraseGrow: self
call SizeWindow \ resize the window
fixGrow: self ;M
:M ZOOM: { part -- } word0 (abs) where: fEvent
part makeint call TrackBox i->l
IF eraseGrow: self get: zoom
IF part 7 - exec: zoom \ execute special zoom
ELSE (abs) part makeint word0 call zoomWindow \ default zoom
THEN
fixGrow: self
THEN ;M
\ ( -- ) response to grow region click
:M GROW: Get: growFlg
IF 0 (abs) Where: fEvent abs: growrect
call GrowWindow -dup
IF unpack size: self draw: self
penIntoWind: self \ go to new bottom
THEN
THEN (abs) call SelectWindow ;M
\ ( -- ) Handle a content click
:M CONTENT: Active: self
IF exec: content \ call the content handler
ELSE (abs) call SelectWindow THEN ;M
\ ( close enact draw cont -- ) init window event handler words
:M ACTIONS: put: content put: draw put: enact
put: close ;M
\ ( addr len -- )
:M TITLE: str255 (abs) swap call SetWTitle ;M
\ ( addr len -- ) Name: is for string class compatibility
:M NAME: title: self ;M
\ ( -- addr len ) return name of window
:M GETNAME: (abs) buf255 +base call GetWTitle
buf255 count ;M
\ ( x y -- )
:M MOVETO: Pack (abs) swap false makeInt
call MoveWindow ;M
:M CENTER: { \ sw sh pw ph -- }
screenBits -> sh -> sw 2drop
size: portRect -> ph -> pw
sw pw - 2/ sh ph - 2/ moveto: self ;M
:M CUT: null ;M
:M COPY: null ;M
:M PASTE: null ;M
:M CLEAR: null ;M
\ ( chr -- ) just drop keys
:M KEY: drop ;M
\ ( -- ) Make this window visible
:M SHOW: (abs) call ShowWindow ;M
\ ( -- ) Make this window visible
:M HIDE: (abs) call HideWindow ;M
\ ( l t r b t OR f -- ) set grow limits
:M SETGROW: DUP put: GrowFlg
IF put: growrect THEN ;M
\ ( l t r b t OR f -- ) Set drag limits
:M SETDRAG: dup Put: dragFlg
IF Put: dragRect THEN ;M
\ ( cfa -- ) set the draw handler
:M SETDRAW: put: draw ;M
:M CLASSINIT:
<[ 4 ]> 'cfas null null null null actions: self
'c null put: idle
'c null put: deact
;M
\ ( -- ) show an example of Window; use grayRgn for drag limits
:M EXAMPLE: 100 100 300 200 put: tempRect \ set size of window
tempRect " Example"
docWind true true new: self
grayRgn true setDrag: self ;M
;CLASS
' Window 'c fWind !